package com.xiaoma.socket

import android.app.Application
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

object PortManager {
    private const val DEFAULT_PORT = 9999

    private val scope = CoroutineScope(Dispatchers.Default)

    private val context = MutableStateFlow<Application?>(null)

    private val Context.dataStore by preferencesDataStore(name = "port-cache")
    private val portKey = intPreferencesKey("com.xiaoma.key.PORT")

    val port = context.filterNotNull().flatMapLatest { app ->
        app.dataStore.data.map { it[portKey] ?: DEFAULT_PORT }
    }.stateIn(scope, SharingStarted.Eagerly, DEFAULT_PORT)

    fun prepare(app: Application) = context.update { app }

    init {
        scope.launch {
            context.filterNotNull().collect { app ->
                val filter = IntentFilter("com.xiaoma.action.SETUP_PORT")
                val receiver = object : BroadcastReceiver() {
                    override fun onReceive(context: Context?, intent: Intent?) {
                        intent ?: return
                        val port = intent.extras?.getInt("port") ?: return
                        scope.launch {
                            app.dataStore.edit { it[portKey] = port }
                        }
                    }
                }
                app.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED)
            }
        }
    }
}